#pragma once

#include "Comm.hpp"
#include "Socket.hpp"
#include "Channel.hpp"
#include "EventLoop.hpp"


class Acceptor
{
private:
    using AcceptCallback = std::function<void(int)>;

    // 监听 socket 的读事件回调函数 
    void HandleRead()
    {
        int newfd = _socket.Accept();
        if (newfd < 0) return;
        if (_accept_callback) _accept_callback(newfd);
    }

    int CreateServer(in_port_t port)
    {
        bool ret = _socket.CreateServer(port);
        assert(ret == true);
        return _socket.GetFd();
    }

public:
    Acceptor(EventLoop* loop, in_port_t port)
        : _socket(CreateServer(port)), 
          _loop(loop), 
          _channel(_socket.GetFd())
    {
        _channel.RegisterOperator(
            std::bind(&EventLoop::UpdateEvent, _loop, &_channel), 
            std::bind(&EventLoop::RemoveEvent, _loop, &_channel));
        _channel.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
    }

    void SetAcceptCallback(const AcceptCallback& cb) { _accept_callback = cb; }

    void Listen() { _channel.EnableRead(); }

    ~Acceptor()
    {
        ::close(_socket.GetFd());
    }

private:
    Socket _socket;                   // 创建监听套接字 
    EventLoop* _loop;                 // 对监听 socket 进行事件监控 
    Channel _channel;                 // 对监听 fd 进行事件管理 
    AcceptCallback _accept_callback;  // 回调函数 
};

